package violin.web.results;

import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import static violin.Configuration.resolveClassAlias;
import violin.annotations.Result;

import java.io.StringWriter;
import java.lang.reflect.Method;

public class VelocityResult {
    private final Object resource;
    private final Object returnValue;
    private final Method targetMethod;

    public VelocityResult(Object resource, Object returnValue, Method targetMethod) {
        this.resource = resource;
        this.returnValue = returnValue;
        this.targetMethod = targetMethod;
    }

    private String resolveViewName(Object returnValue, Method method, Object resource) {
        String viewName = null;
        if (method.isAnnotationPresent(Result.class)) {
            Result annotation = method.getAnnotation(Result.class);
            if (!annotation.value().equals("")) {
                viewName = annotation.value();
            } else if (annotation.navigator() != null) {
                try {
                    viewName = annotation.navigator().newInstance().navigate(returnValue, resource);
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
        if (viewName == null || viewName.equals("")) {
            viewName = method.getName();
        }

        return viewName;
    }

    @Override
    public String toString() {
        String viewName = resolveViewName(returnValue, targetMethod, resource);
        StringWriter writer = new StringWriter();
        try {
            Velocity.init();
            VelocityContext context = new VelocityContext();

            String returnClassName = resolveClassAlias(returnValue.getClass());
            String resourceName = resolveClassAlias(resource.getClass());
            context.put(returnClassName, returnValue);
            context.put(resourceName, resource);
            Velocity.mergeTemplate("/templates/" + viewName + ".vm", "UTF-8", context, writer);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return writer.toString();
    }
}
